(defun ceshell-buffer(arg)
  "cycle through buffers whose major mode is term-mode"
  (interactive)
  (setq works (buffer-list))
  (setq createshell 1)
  (while works
	(when (with-current-buffer (car works)
			(string= arg (buffer-name)))
	  (switch-to-buffer (car works))
	  (setq createshell 0)
	  (setq works nil))
	(setq works (cdr works)))
  (if( = createshell 1) (eshell))
  (if( = createshell 1) (rename-buffer arg))
  )
(defun workshell ()
  (interactive)
  (when (null (cdr (window-list)))
    (split-window-vertically))
  (let (file buffer-file-name)
	;;    (other-window 1)
    (ceshell-buffer "work-shell")
    (when file
      (end-of-buffer)
      (when (looking-back shell-prompt-pattern)
        (insert "cd " (file-name-directory file))
        (call-interactively 'comint-send-input))
      )
    )
  )
(defun eshell/e (file)
  (find-file file))
(defun eshell/ee (file)
  (find-file-other-window file))

(defun eshell/ca ()
  (kill-some-buffers))

(defun eshell/c ()
  "04Dec2001 - sailor, to clear the eshell buffer."
  (interactive)
  (let ((inhibit-read-only t))
	(erase-buffer)))

(defun dos2unix (buffer)
  "Automate M-% C-q C-m RET C-q C-j RET"
  (interactive "*b")
  (save-excursion
    (goto-char (point-min))
    (while (search-forward (string ?\C-m) nil t)
      (replace-match (string ?\C-j) nil t))))

(defun progmodes-hooks ()
  "Hooks for programming modes"
  (add-hook 'before-save-hook 'progmodes-write-hooks))

(defun progmodes-write-hooks ()
  "Hooks which run on file write for programming modes"
  (prog1 nil
    (delete-trailing-whitespace)))

(add-hook 'c-mode-common-hook 'progmodes-hooks)

(defun clear-shell ()
  (interactive)
  (let ((comint-buffer-maximum-size 0))
	(comint-truncate-buffer)))
(defun xah-shrink-whitespaces ()
  "Remove whitespaces around cursor to just one or none.
Call this command again to shrink more. 3 calls will remove all whitespaces.
URL `http://ergoemacs.org/emacs/emacs_shrink_whitespace.html'
Version 2016-12-18"
  (interactive)
  (let ((-p0 (point))
        -line-has-char-p ; current line contains non-white space chars
        -has-space-tab-neighbor-p
        -space-or-tab-begin -space-or-tab-end
        )
    (save-excursion
      (setq -has-space-tab-neighbor-p
            (or (looking-at " \\|\t") (looking-back " \\|\t" 1)))
      (beginning-of-line)
      (setq -line-has-char-p (re-search-forward "[[:graph:]]" (line-end-position) t))
      (goto-char -p0)
      (skip-chars-backward "\t ")
      (setq -space-or-tab-begin (point))
      (goto-char -p0)
      (skip-chars-forward "\t ")
      (setq -space-or-tab-end (point)))
    (if -line-has-char-p
        (if -has-space-tab-neighbor-p
            (let (-deleted-text)
              ;; remove all whitespaces in the range
              (setq -deleted-text
                    (delete-and-extract-region -space-or-tab-begin -space-or-tab-end))
              ;; insert a whitespace only if we have removed something different than a simple whitespace
              (when (not (string= -deleted-text " "))
                (insert " ")))
          (progn
            (when (equal (char-before) 10) (delete-char -1))
            (when (equal (char-after) 10) (delete-char 1))))
      (progn (delete-blank-lines)))))
(defun xah-quote-lines ()
  "Change current text block's lines to quoted lines with comma or other separator char.
When there is a text selection, act on the selection, else, act on a text block separated by blank lines.

For example,

 cat
 dog
 cow

becomes

 \"cat\",
 \"dog\",
 \"cow\",

or

 (cat)
 (dog)
 (cow)

If the delimiter is any left bracket, the end delimiter is automatically the matching bracket.

URL `http://ergoemacs.org/emacs/emacs_quote_lines.html'
Version 2017-01-08"
  (interactive)
  (let* (
         -p1
         -p2
         (-quoteToUse
          (read-string
           "Quote to use:" "\"" nil
           '(
             ""
             "\""
             "'"
             "("
             "{"
             "["
             )))
         (-separator
          (read-string
           "line separator:" "," nil
           '(
             ""
             ","
             ";"
             )))
         (-beginQuote -quoteToUse)
         (-endQuote
          ;; if begin quote is a bracket, set end quote to the matching one. else, same as begin quote
          (let ((-syntableValue (aref (syntax-table) (string-to-char -beginQuote))))
            (if (eq (car -syntableValue ) 4) ; ; syntax table, code 4 is open paren
                (char-to-string (cdr -syntableValue))
              -quoteToUse
              ))))
    (if (use-region-p)
        (progn
          (setq -p1 (region-beginning))
          (setq -p2 (region-end)))
      (progn
        (if (re-search-backward "\n[ \t]*\n" nil "NOERROR")
            (progn (re-search-forward "\n[ \t]*\n")
                   (setq -p1 (point)))
          (setq -p1 (point)))
        (re-search-forward "\n[ \t]*\n" nil "NOERROR")
        (skip-chars-backward " \t\n" )
        (setq -p2 (point))))
    (save-excursion
      (save-restriction
        (narrow-to-region -p1 -p2)
        (goto-char (point-min))
        (skip-chars-forward "\t ")
        (insert -beginQuote)
        (goto-char (point-max))
        (insert -endQuote)
        (goto-char (point-min))
        (while (re-search-forward "\n\\([\t ]*\\)" nil "NOERROR" )
          (replace-match
           (concat -endQuote -separator (concat "\n" (match-string 1)) -beginQuote) "FIXEDCASE" "LITERAL"))
        ;;
        ))))

(defun xah-open-file-at-cursor ()
  "Open the file path under cursor.
If there is text selection, uses the text selection for path.
If the path starts with “http://”, open the URL in browser.
Input path can be {relative, full path, URL}.
Path may have a trailing “:‹n›” that indicates line number. If so, jump to that line number.
If path does not have a file extension, automatically try with “.el” for elisp files.
This command is similar to `find-file-at-point' but without prompting for confirmation.

URL `http://ergoemacs.org/emacs/emacs_open_file_path_fast.html'"
  (interactive)
  (let ((-path (if (use-region-p)
                   (buffer-substring-no-properties (region-beginning) (region-end))
                 (let (p0 p1 p2)
                   (setq p0 (point))
                   ;; chars that are likely to be delimiters of full path, e.g. space, tabs, brakets.
                   (skip-chars-backward "^  \"\t\n`'|()[]{}<>〔〕“”〈〉《》【】〖〗«»‹›·。\\`")
                   (setq p1 (point))
                   (goto-char p0)
                   (skip-chars-forward "^  \"\t\n`'|()[]{}<>〔〕“”〈〉《》【】〖〗«»‹›·。\\'")
                   (setq p2 (point))
                   (goto-char p0)
                   (buffer-substring-no-properties p1 p2)))))
    (if (string-match-p "\\`https?://" -path)
        (browse-url -path)
      (progn ; not starting “http://”
        (if (string-match "^\\`\\(.+?\\):\\([0-9]+\\)\\'" -path)
            (progn
              (let (
                    (-fpath (match-string 1 -path))
                    (-line-num (string-to-number (match-string 2 -path))))
                (if (file-exists-p -fpath)
                    (progn
                      (find-file -fpath)
                      (goto-char 1)
                      (forward-line (1- -line-num)))
                  (progn
                    (when (y-or-n-p (format "file doesn't exist: 「%s」. Create?" -fpath))
                      (find-file -fpath))))))
          (progn
            (if (file-exists-p -path)
                (find-file -path)
              (if (file-exists-p (concat -path ".el"))
                  (find-file (concat -path ".el"))
                (when (y-or-n-p (format "file doesn't exist: 「%s」. Create?" -path))
                  (find-file -path ))))))))))
(defun list-funcs (arg)
  "List functions in buffer." (interactive "p") (message "functions")
  ;;;  (list-matching-lines "^\\bstatic\\b*\\binline\\b*[ ]*[A-Za-z_<>]+[ ]+[A-Za-z0-9_:]+[\(]"))
  (split-window-horizontally)
  (other-window 1)
  (list-matching-lines "^[A-Za-z0-9_]+[ ]+[A-Za-z0-9_<>: ]*[\(]"))

(defun kill-all-buffer ()
  "Kill all buffer."
  (interactive)
  (dolist (buffer (buffer-list)) (kill-buffer buffer)))

(defun kill-other-buffer ()
  "Close all of other buffer."
  (interactive)
  (dolist (buffer (delq (current-buffer) (buffer-list))) (kill-buffer buffer)))

(defun eshell/vi (&rest args)
  "Invoke `find-file' on the file.
\"vi +42 foo\" also goes to line 42 in the buffer."
  (while args
    (if (string-match "\\`\\+\\([0-9]+\\)\\'" (car args))
        (let* ((line (string-to-number (match-string 1 (pop args))))
               (file (pop args)))
          (find-file file)
          (goto-line line))
      (find-file (pop args)))))

(defun eshell/vim (&rest args)
  "Invoke `find-file' on the file.
\"vi +42 foo\" also goes to line 42 in the buffer."
  (while args
    (if (string-match "\\`\\+\\([0-9]+\\)\\'" (car args))
        (let* ((line (string-to-number (match-string 1 (pop args))))
               (file (pop args)))
          (find-file file)
          (goto-line line))
      (find-file (pop args)))))
